package com.dreamlin.app.base.ui

import android.annotation.SuppressLint
import android.content.Context
import android.content.pm.ActivityInfo
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.Toast
import androidx.annotation.LayoutRes
import androidx.annotation.MenuRes
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.lifecycle.Observer
import com.dreamlin.app.App
import com.dreamlin.app.base.model.BaseViewModel
import com.dreamlin.app.common.isFastDoubleClick
import com.dreamlin.app.widget.FloatingBall
import com.gyf.immersionbar.ImmersionBar

abstract class NoVMActivity : AppCompatActivity(), View.OnClickListener {
    private lateinit var mContext: Context
    private lateinit var loadingDialog: LoadingDialog
    private var toast: Toast? = null
    private var floatingBall: FloatingBall? = null

    @SuppressLint("SourceLockedOrientationActivity")
    override fun onCreate(savedInstanceState: Bundle?) {
        requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
        initBar()
        super.onCreate(savedInstanceState)
        mContext = this
        loadingDialog = LoadingDialog(mContext)
        toast = Toast.makeText(mContext, "", Toast.LENGTH_SHORT)
        setContentView(layout)
        initViews()
        initData()
    }

    @get:LayoutRes
    abstract val layout: Int

    abstract fun initViews()

    abstract fun initData()

    abstract fun click(view: View)

    override fun onClick(view: View) {
        //加一层拦截 防止快速点击
        if (isFastDoubleClick(view.id)) return
        click(view)
    }

    open fun initBar() {
        ImmersionBar.with(this)
            .transparentStatusBar()
            .statusBarDarkFont(true)
            .init()
    }

    @MenuRes
    open fun getMenu(): Int = -0x01

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {

        if (getMenu() != -0x01) {
            menuInflater.inflate(getMenu(), menu)
            return true
        }

        return super.onCreateOptionsMenu(menu)
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {

        when (item.itemId) {
            android.R.id.home -> {
                onBackPressed()
                return true
            }
        }
        return super.onOptionsItemSelected(item)
    }

    override fun onResume() {
        super.onResume()

    }

    override fun onStop() {
        super.onStop()
        hideLoading()
    }

    fun showLoading(msg: String? = null) {
        if (loadingDialog == null) {
            loadingDialog = LoadingDialog(mContext)
        }
        loadingDialog.show()
        loadingDialog.setLoadingMsg(msg)
    }

    fun hideLoading() {
        if (loadingDialog.isShowing) loadingDialog.dismiss()
    }

    @SuppressLint("ShowToast")
    fun toast(msg: String, duration: Int = Toast.LENGTH_SHORT) {
        if (toast == null) {
            toast = Toast.makeText(mContext, msg, duration)
        } else {
            toast?.apply {
                setDuration(duration)
                setText(msg)
            }
        }
        toast?.show()
    }

    fun toast(@StringRes resId: Int, duration: Int = Toast.LENGTH_SHORT) {
        if (toast == null) {
            toast = Toast.makeText(mContext, resId, duration)
        } else {
            toast?.apply {
                setDuration(duration)
                setText(resId)
            }
        }
        toast?.show()
    }

}

abstract class BaseActivity<VM : BaseViewModel> : NoVMActivity() {
    lateinit var viewModel: VM

    override fun onCreate(savedInstanceState: Bundle?) {
        viewModel = App.getViewModelProvider().create(getVM())
        initObserver()
        super.onCreate(savedInstanceState)
    }

    abstract fun getVM(): Class<VM>

    private fun initObserver() {
        viewModel.initDialog(this, Observer {
            when (it.isShow) {
                true -> showLoading(it.msg)
                false -> hideLoading()
            }
        })

        viewModel.initError(this, Observer {
            toast(it)
            onError()
        })
    }

    /**
     * 如果有刷新等逻辑
     * 需在错误逻辑里进行处理
     */
    open fun onError() {

    }
}